﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RedisDBBiz;
using PriceCacheDownloader;
using RoomPriceEntity;
using DataLoader;
using HotelMatchUtility.Utility;
using CommonUtility;
using System.Threading.Tasks;
using System.Threading;
using FileSystem;
using ProDataUpdater;

namespace Redis_DataLoader
{
    public class ExecMain
    {
        public static int DoneHotelCount = 0;
        public static int ErrorHotelCount = 0;
        public static string GetOpenHotelURL = "https://distribution-xml.booking.com/json/bookings.getHotels";
        public static string GetHotelAvailURL = "https://distribution-xml.booking.com/json/bookings.getHotelAvailability";
        public static string GetBlockAvailURL = "https://distribution-xml.booking.com/json/bookings.getBlockAvailability";
        public static RoomPriceGetRedis rs = new RoomPriceGetRedis();
        public static DateTime dtStandard = new DateTime(2014, 10, 21);
        private static System.Threading.Timer timer = null;
        private static string fileName = "Booking_300.csv";
        private static object lo = new object();

        public static void Main(string[] args)
        
        {
            List<string> hotelCodeList = rs.GetList("Min_LOS_AgodaOver7:8");
            foreach (var str in hotelCodeList)
            {
                NormalFileWriter.WriteTextToFile(str, "C:\\FileOutputSystem", "Agoda_noRS.sql");
            }
            //OutputDb_StrategySP2();
            //List<string> hotelCodeList = Y_FileReader.ReadIdFromFile(@"C:\agoda_noprice.txt");
            //foreach (var code in hotelCodeList)
            //{
            //    ExecAgodaRequest.CheckIfAgodaHasMultiPrice(code);
            //}
            //OutputDB_SP();
            //OutputDB_SP_BackUp();
            //OutputDB_StrategySP();
            //OutputDb_StrategySP2();
            //DateTime start = DateTime.Now;
            //timer = new System.Threading.Timer(p =>
            //{
            //    Console.WriteLine(start.ToString("yyyy/MM/dd HH:mm:ss") + " Done:[" + DoneHotelCount + "] " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
            //              + "[ErrorCount]:" + ErrorHotelCount);
            //}, null, 1000, 1000);
            //Test_2();
            //20140901
            //rs.FlushDB();
            //AddBookingCodeToRedis();
            //DateTime start = DateTime.Now;
            //timer = new System.Threading.Timer(p =>
            //{
            //    Console.WriteLine(start.ToString("yyyy/MM/dd HH:mm:ss") + " Done:[" + DoneHotelCount + "] " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")
            //              );
            //}, null, 1000, 1000);
            ////Test_Booking();
            ////step2
            //Test_Booking_Step2();
            //AddBookingCodeToRedis();
            //RoomPriceSaveRedis1 tst = new RoomPriceSaveRedis1();
            //tst.RedisSetRoomPrice_Group(33, 5000, tst.RedisSetRoomPrice_List1);

            //20140902
            //ReadRedisToCsv rs = new ReadRedisToCsv();
            //rs.GetHotelCodeFile();

            

            //DoCompare();

            //tst.RedisSetRoomPrice_1(645071);
            //Test_1();

            //ReadRedisToCsv rc = new ReadRedisToCsv();
            //List<string> ls = rc.GetKeys();
            //rc.RedisToDB(ls);

            //RoomPriceGetRedis getRedis = new RoomPriceGetRedis();
            //var hotelList = getRedis.GetList("hotelList");
            //foreach (var hotel in hotelList)
            //{
            //    FileSystem.NormalFileWriter.WriteTextToFile(hotel, "C:\\FileOutputSystem", "HotelList.csv");
            //}
        }

        public static void AddBookingCodeToRedis()
        {
            List<string> hotelCodeList = Y_FileReader.ReadIdFromFile(@"C:\bookingCode.txt") ;
            RoomPriceGetRedis rs = new RoomPriceGetRedis();
            rs.SetList(hotelCodeList);
        }

        public static void Test_Booking()
        {
            
            List<string> hotelCodeList = rs.GetList("BookingHotelCode");
            try
            {
                //Parallel.ForEach(hotelCodeList, Dowork);
                for (int i = 5915; i < hotelCodeList.Count; i++)
                {
                    //Dowork(hotelCodeList[i]);
                }
                //foreach (var hotelCode in hotelCodeList)
                //{
                //    Dowork(hotelCode);
                //}
            }
            catch(Exception ex)
            {
            }

        }

        public static void Test_Booking_Step2()
        {
            ReadRedisToCsv rs = new ReadRedisToCsv();
            List<string> ls = rs.redisClient.GetRangeFromList("Timeout", 0, -1);
            foreach (var hotelCode in ls)
            {
                Dowork(hotelCode, true, 2, 30);
            }

            List<string> ls_10 = rs.redisClient.GetRangeFromList("Min_LOS:10+", 0, -1);
            foreach (var hotelCode in ls_10)
            {
                Dowork(hotelCode, false, 10, 30);
            }
        }

        public static void Dowork(string hotelCode, bool checkGetHotel, int startLos, int endLos)
        {
            try
            {
                Interlocked.Increment(ref DoneHotelCount);
                int min_los = startLos;
                RequestCreater rc = new RequestCreater(new List<string>() { hotelCode });
                bool IsOpenHotel = false;
                if (checkGetHotel)
                {
                    string rqGetHotel = rc.GetBookingIsHotelXmlBody();
                    string rsGetHotel = Requestor.DoRequest(rqGetHotel, GetOpenHotelURL, true);
                    List<BookingGetHotelResponseEntity> getHotelRsEntityList = JsonHelper.JsonDeserialize<List<BookingGetHotelResponseEntity>>(rsGetHotel);
                    IsOpenHotel = getHotelRsEntityList != null && getHotelRsEntityList.Count > 0
                        && getHotelRsEntityList.FirstOrDefault() != null
                        && !string.IsNullOrEmpty(getHotelRsEntityList.FirstOrDefault().hotel_id);
                }
                // Do OpenHotelRequestCheck
                if (!checkGetHotel || IsOpenHotel)
                {
                    //rs.SetItem("HotelCode:" + hotelCode + ":HotelType_ID", getHotelRsEntityList.FirstOrDefault().hoteltype_id.ToString());
                    //rs.AddItemToList("HotelType_ID:" + getHotelRsEntityList.FirstOrDefault().hoteltype_id, hotelCode);
                    // min_los 2 - 10
                    while (min_los <= endLos)
                    {
                        //Do checkHotelAvail
                        DateTime arrival = dtStandard;
                        DateTime departure = arrival.AddDays(min_los);
                        rc.SetArrival(arrival);
                        rc.SetDeparture(departure);
                        string requestXml = rc.GetBookingRequestXmlBody();
                        string response = Requestor.DoRequest(requestXml, GetHotelAvailURL, true);
                        List<BookingHotelAvlResponseEntity> hotelAvl = JsonHelper.JsonDeserialize<List<BookingHotelAvlResponseEntity>>(response);
                        bool isGetPrice = hotelAvl != null && hotelAvl.Count > 0 && hotelAvl.FirstOrDefault().min_price > 0;
                        if (isGetPrice)
                        {
                            rs.AddItemToList("Min_LOS:" + min_los, hotelCode);
                            //rs.SetItem("HotelCode:" + hotelCode + ":Min_LOS", min_los.ToString());
                            break;
                        }
                        else
                        {
                            min_los++;
                        }
                    }
                    if (min_los > endLos)
                    {
                        rs.AddItemToList("Min_LOS:" + endLos + "+", hotelCode);
                    }
                }
                else
                {
                    rs.AddItemToList("Closed", hotelCode);
                }
            }
            catch (Exception ex)
            {
                rs.AddItemToList("Timeout", hotelCode);
            }
        }

        public static void Test_2()
        {
            List<string> hotelCodeList = Y_FileReader.ReadIdFromFile(@"C:\b300.txt");
            List<List<string>> GroupHotelCodeList = new List<List<string>>();
            int count = 0;
            List<string> inner = new List<string>();
            foreach (var hotelcode in hotelCodeList)
            {
                count++;
                inner.Add(hotelcode);
                if (count % 20 == 0 || count == hotelCodeList.Count)
                {
                    GroupHotelCodeList.Add(inner);
                    inner = new List<string>();
                }
                
            }
            //Parallel.ForEach(GroupHotelCodeList, new ParallelOptions { MaxDegreeOfParallelism = 3 }
            //    , (p, state) => { Dowork2(p); });
            
            foreach (var list in GroupHotelCodeList)
            {
                Dowork2(list);
            }
        }

        public static void Dowork2(List<string> hotelCodeList)
        {
            try
            {
                RequestCreater rc = new RequestCreater(hotelCodeList);
                DateTime[] dtArray = new DateTime[]
            {
                new DateTime(2014, 9, 29),
                new DateTime(2014, 10, 03),
                new DateTime(2014, 10, 11),
                new DateTime(2014, 10, 26),
                new DateTime(2014, 12, 25)
            };
                foreach (var dt in dtArray)
                {
                    List<BookingBlockAvlResponseEntity> hotelAvl = new List<BookingBlockAvlResponseEntity>();
                    int retry = 0;
                    while (retry < 3)
                    {
                        try
                        {
                            DateTime arrival = dt;
                            DateTime departure = arrival.AddDays(1);
                            rc.SetArrival(arrival);
                            rc.SetDeparture(departure);
                            string requestXml = rc.GetBookingRequestXmlBody();
                            string response = Requestor.DoRequest(requestXml, GetBlockAvailURL, true);
                            hotelAvl = JsonHelper.JsonDeserialize<List<BookingBlockAvlResponseEntity>>(response);
                            OutPutAvl(hotelAvl);
                            Thread.Sleep(1000);
                            break;
                        }
                        catch
                        {
                            Thread.Sleep(5000);
                            retry++;
                        }
                    }
                    if (retry >= 3)
                    {
                        Interlocked.Increment(ref ErrorHotelCount);
                    }
                }
                Interlocked.Increment(ref DoneHotelCount);
            }
            catch
            {
                Interlocked.Increment(ref ErrorHotelCount);
            }
        }

        public static void OutPutAvl(List<BookingBlockAvlResponseEntity> hotelAvl)
        {  
            foreach (var blockRs in hotelAvl)
            {
                foreach (var blockIn in blockRs.BlockList)
                {
                    StringBuilder line = new StringBuilder();
                    line.Append(blockRs.hotel_id).Append(",");
                    line.Append(blockRs.arrival_date).Append(",");
                    line.Append(blockIn.name.Trim().Replace("\n", "")).Append(",");
                    line.Append(blockIn.minPrice.currency).Append(",");
                    line.Append(blockIn.minPrice.price).Append(",");
                    double taxfee = 0 ;
                    if (blockIn.minPrice.extraChargesBreakdown != null && blockIn.minPrice.extraChargesBreakdown.ExtraChargeList != null
                        && blockIn.minPrice.extraChargesBreakdown.ExtraChargeList.Count > 0)
                    {
                        foreach (var exCharge in blockIn.minPrice.extraChargesBreakdown.ExtraChargeList)
                        {
                            taxfee += exCharge.amount;
                        }
                    }
                    line.Append(blockIn.minPrice.price - taxfee).Append(",");

                    line.Append(blockIn.minPrice.otherCurrency.currency).Append(",");
                    line.Append(blockIn.minPrice.otherCurrency.price);

                    lock (lo)
                    {
                        NormalFileWriter.WriteTextToFile(line.ToString(), "C:\\FileOutputSystem", fileName);
                    }
                }
            }
        }

        public static void Test_1()
        {
            string TestUrl = "http://cxml.agoda.com/xmlpartner/XmlService.svc/search_lrv2" ;
            RoomPriceGetRedis getRedis = new RoomPriceGetRedis();
            DateTime dtToday = DateTime.Today;
            var hotelList = getRedis.GetList("hotelList");
            Converter cv = new Converter();

            foreach (var hotel in hotelList)
            {
                for (int i = 1; i <= 180; i++)
                {
                    DateTime arrival = dtToday.AddDays(i);
                    DateTime departure = arrival.AddDays(1);
                    string hotelCode = cv.GetHotelCode(int.Parse(hotel) ) ;
                    RequestCreater rc = new RequestCreater(hotelCode);
                    rc.SetArrival(arrival);
                    rc.SetDeparture(departure);
                    string requestXml = rc.GetAgodaRequestXml();
                    string response= Requestor.DoRequest(requestXml, TestUrl);
                    List<PriceEntity> entityList = cv.GetPriceEntity(response);
                    foreach (var e in entityList)
                    {
                        e.effectdate = arrival;
                    }
                }
            }
        }



        public static void DoCompare()
        {
            List<int> roomList = PriceLoader.GetChangedRoomList();
            RoomPriceGetRedis getRedis = new RoomPriceGetRedis();
            getRedis.DoCompare(roomList);
        }

        public static void OutputDb_StrategySP2()
        {
            ReadRedisToCsv rs = new ReadRedisToCsv();
            List<string> ls_10 = rs.redisClient.GetRangeFromList("Min_LOS_Agoda:2", 0, -1);
            //var resultList = Y_FileReader.ReadEntityFromFile("D:/769.csv");
            foreach (var hotelCode in ls_10)
            {
                var stgList = InterfaceDB.GetPriceStrategy(hotelCode);
                PriceCacheStrategyEntity stg1 = null;
                bool flg = true;
                if (stgList.Count > 0)
                {
                    foreach (var stg in stgList)
                    {
                        if (flg)
                        {
                            stg1 = stg;
                            flg = false;
                        }
                        string updateStr = string.Format(@"Exec SpA_Htl_If_PriceCacheStrategy_U @PriceCacheStrategyId={0}, @IsEnable='S'", stg.PriceCacheStrategyID);
                        NormalFileWriter.WriteTextToFile(updateStr, "C:\\FileOutputSystem", "Agoda_StrategyUpdate_2.sql");
                    }
                    string insertStr = string.Format(@"Exec SpA_Htl_IF_PriceCacheStrategy_I @PriceCacheStrategyId=1, @GroupID=32,@HotelCode='{0}',@Hotel={1},@City={2},@Country={3},@PriceCachePriorityCode='2K_A'{4},@PriceCacheTypeCode='{5}',@PriceCacheStatus='S',@LastStartTime='2014-01-01',@LastEndTime='2014-01-01',@StartTime='2014-01-01',@EndTime='2014-01-01',@IsEnable='T',@Updater='LOS_Update',@DataChange_LastTime='2014-01-01',@PriceCacheScheduleCode='{6}',@IsNeedHistory='T'"
                        , stg1.HotelCode, stg1.Hotel, stg1.City, stg1.Country, "", "MLOS" + 2, stg1.PriceCacheScheduleCode);
                    NormalFileWriter.WriteTextToFile(insertStr, "C:\\FileOutputSystem", "Agoda_StrategyUpdate_2.sql");
                }
            }
             

        }

        public static void OutputDB_StrategySP()
        {
            
            int LEN = 30;
            ReadRedisToCsv rs = new ReadRedisToCsv();
            for (int i = 2; i <= LEN; i++)
            {
                int indexOfRateCodeArray = i - 2;
                List<string> HotelCodeList = rs.redisClient.GetRangeFromList("Min_LOS:" + i, 0, -1);
                NormalFileWriter.WriteTextToFile(
                        string.Format(@" ---------------- Stg Update Part {0} Start------------------------", i - 1)
                        , "C:\\FileOutputSystem", "Booking_FG_StrategyUpdate.sql");
                foreach (var hotelCode in HotelCodeList)
                {
                    var stgList = InterfaceDB.GetPriceStrategy(hotelCode);
                    PriceCacheStrategyEntity stg1 = null;
                    bool flg = true;
                    if (stgList.Count > 0)
                    {
                        foreach (var stg in stgList)
                        {
                            if (flg)
                            {
                                stg1 = stg;
                                flg = false;
                            }
                            string updateStr = string.Format(@"Exec SpA_Htl_If_PriceCacheStrategy_U @PriceCacheStrategyId={0}, @IsEnable='S'", stg.PriceCacheStrategyID);
                            NormalFileWriter.WriteTextToFile(updateStr, "C:\\FileOutputSystem", "Booking_FG_StrategyUpdate_769.sql");
                        }
                        string insertStr = string.Format(@"Exec SpA_Htl_IF_PriceCacheStrategy_I @PriceCacheStrategyId=1, @GroupID=32,@HotelCode='{0}',@Hotel={1},@City={2},@Country={3},@PriceCachePriorityCode='2K_A'{4},@PriceCacheTypeCode='{5}',@PriceCacheStatus='S',@LastStartTime='2014-01-01',@LastEndTime='2014-01-01',@StartTime='2014-01-01',@EndTime='2014-01-01',@IsEnable='T',@Updater='LOS_Update',@DataChange_LastTime='2014-01-01',@PriceCacheScheduleCode='{6}',@IsNeedHistory='T'"
                            , stg1.HotelCode, stg1.Hotel, stg1.City, stg1.Country, "", "MLOS" + i, stg1.PriceCacheScheduleCode);
                        NormalFileWriter.WriteTextToFile(insertStr, "C:\\FileOutputSystem", "Booking_FG_StrategyUpdate_769.sql");
                    }
                }
                NormalFileWriter.WriteTextToFile(
                     string.Format(@" ---------------- Stg Update Part {0} End------------------------
", i - 1)
                 , "C:\\FileOutputSystem", "Booking_FG_StrategyUpdate_769.sql");
            }
        }

        public static void OutputDB_SP_BackUp()
        {
            List<int> RoomIdList = new List<int>() ;
            int LEN = 30;
            ReadRedisToCsv rs = new ReadRedisToCsv();
            for (int i = 2; i <= LEN; i++)
            {
                int indexOfRateCodeArray = i - 2;
                List<string> HotelCodeList = rs.redisClient.GetRangeFromList("Min_LOS:" + i, 0, -1);
                foreach (var hotelCode in HotelCodeList)
                {
                    int RoomId = InterfaceDB.GetRoomByHotelCode(hotelCode);
                    if (RoomId != 0)
                    {
                        RoomIdList.Add(RoomId);
                    }
                }
            }

            StringBuilder sbWhere = new StringBuilder();
            int BackUpID = 1;
            for (int i = 0; i < RoomIdList.Count(); i++)
            {
                
                sbWhere.Append(RoomIdList[i]).Append(",");
                if (i != 0 && i % 3500 == 0 || i == RoomIdList.Count() - 1)
                {
                    NormalFileWriter.WriteTextToFile(
                        string.Format(@" ---------------- Backup Part {0} Start------------------------
", BackUpID)
                    , "C:\\FileOutputSystem", "Booking_FG_RateCodeIdBackUp.sql");
                    string whereClause = "Where Room In (";
                    whereClause += sbWhere.ToString().TrimEnd(',') + ")";
                    NormalFileWriter.WriteTextToFile(
                        @"Select * From RoomType(nolock) " + whereClause
                    , "C:\\FileOutputSystem", "Booking_FG_RateCodeIdBackUp.sql");
                    NormalFileWriter.WriteTextToFile(
                        string.Format(@" ---------------- Backup Part {0} End------------------------
", BackUpID)
                    , "C:\\FileOutputSystem", "Booking_FG_RateCodeIdBackUp.sql");
                    BackUpID++;
                    sbWhere = new StringBuilder();
                }
            }
        }

        public static void OutputDB_SP()
        {
            int LEN = 30;
            ReadRedisToCsv rs = new ReadRedisToCsv();
            for (int i = 2; i <= LEN; i++)
            {
                int indexOfRateCodeArray = i - 2;
                List<string> HotelCodeList = rs.redisClient.GetRangeFromList("Min_LOS:" + i, 0, -1);
                NormalFileWriter.WriteTextToFile(string.Format(@"--------------LOS = {0} start-----------------------",i)
                    , "C:\\FileOutputSystem", "Booking_FG_RateCodeIdUpdate2.sql");
                foreach (var hotelCode in HotelCodeList)
                {
                    int RoomId = InterfaceDB.GetRoomByHotelCode(hotelCode);
                    if (RoomId != 0)
                    {
                        string outputStr = string.Format(@"Exec SpA_RoomType_U @Room={0}, @IsPromoteRoomType='T';
Exec SpA_RoomTypeAll_u @Room={0}, @IsPromoteRoomType='T';", RoomId);
                        NormalFileWriter.WriteTextToFile(outputStr, "C:\\FileOutputSystem", "Booking_FG_RateCodeIdUpdate2.sql");
                    }
                }

                NormalFileWriter.WriteTextToFile(string.Format(@"--------------LOS = {0} end-----------------------
", i)
                    , "C:\\FileOutputSystem", "Booking_FG_RateCodeIdUpdate2.sql");
            }
            
        }

        public static int[] FG_RateCodeArray=new int[] {
            1275294,
1275295,
1275297,
1275303,
1275305,
1275308,
1275310,
1275312,
1275314,
1275316,
1275318,
1275321,
1275323,
1275325,
1275327,
1275331,
1275333,
1275337,
1275339,
1275341,
1275344,
1275347,
1275349,
1275351,
1275352,
1275354,
1275355,
1275356,
1275358
    };

        public static int[] PP_RateCodeArray = new int[]{1275289,
1275292,
1275293,
1275298,
1275300,
1275301,
1275304,
1275306,
1275307,
1275311,
1275315,
1275317,
1275319,
1275320,
1275322,
1275324,
1275326,
1275328,
1275329,
1275332,
1275334,
1275338,
1275340,
1275342,
1275343,
1275345,
1275346,
1275348,
1275350
        };
    }
}
